/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * MazeView.java
 *
 * Created on 22/03/2012, 21:19:41
 */
package minesweeper;

import gtree.DrawTree;
import gtree.Position;
import gtree.Tree;
import java.awt.Component;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import javax.swing.JOptionPane;

/**
 *
 * @author grostirolla
 */
public class MazeView extends javax.swing.JFrame
{

    /**
     * Creates new form MazeView
     */
    private Maze maze;
    private mazeButton[][] buttonMaze;
    String[][] actualState;
    private boolean bombClick = false;
    private DefaultAction action = new DefaultAction();
    // private Tree tree;
    private int DEFAULT_SIZE = 25;
    private int DEFAULT_SPACE = DEFAULT_SIZE + 2;
    private int yPressed = -1, xPressed = -1;
    private int countRevealed = 0;
    private int countPFlagged = 0;
    // private Position lastPosition;
    private boolean showLog = true;
    private ArrayList<String> log;
    logReader lr;

    public MazeView(Maze maze)
    {
        initComponents();
        action.setMazeView(this);
        this.maze = maze;
        this.setSize(maze.getColumns() * DEFAULT_SIZE - DEFAULT_SPACE * 2, maze.getRows() * DEFAULT_SIZE - DEFAULT_SPACE * 2);
        createMaze();
        lr = new logReader();
        /*
         * System.out.print("\n"); for (int[] i : maze.getMaze()) {
         * System.out.print("\n"); for (int x : i) { System.out.print(x + "|");
         * } }
         */

    }

    private void createMaze()
    {
        log = new ArrayList<String>();
        // tree = new Tree("Inicio");
        //  lastPosition = tree.root();
        actualState = new String[maze.getRows()][maze.getColumns()];
        jPanel1.removeAll();
        jPanel1.repaint();
        xPressed = -1;
        yPressed = -1;

        buttonMaze = new mazeButton[this.maze.getRows()][this.maze.getColumns()];
        int posX = 0 - DEFAULT_SPACE, posY = 0 - DEFAULT_SPACE;

        for (int r = 0; r < this.maze.getRows(); r++)
        {
            posY = (posY + DEFAULT_SPACE) % (maze.getRows() * DEFAULT_SPACE);
            for (int c = 0; c < this.maze.getColumns(); c++)
            {
                buttonMaze[r][c] = new mazeButton(c, r, this);
                buttonMaze[r][c].addMouseListener(new MouseListener()
                {

                    @Override
                    public void mouseClicked(MouseEvent me)
                    {
                    }

                    @Override
                    public void mousePressed(MouseEvent me)
                    {
                    }

                    @Override
                    public void mouseReleased(MouseEvent me)
                    {
                        if (me.getButton() == me.BUTTON1)
                        {
                            if (me.getComponent() instanceof mazeButton)
                            {
                                ((mazeButton) me.getComponent()).setSelected(true);
                                log.add("Clicked At X-Y " + xPressed + "-" + yPressed + " Found Value: " + buttonMaze[yPressed][xPressed].getValue());
                                checkClick();
                            }
                        } else if (me.getButton() == me.BUTTON3)
                        {
                            if (me.getComponent() instanceof mazeButton)
                            {
                                ((mazeButton) me.getComponent()).changeFlag();
                            }
                        }
                    }

                    @Override
                    public void mouseEntered(MouseEvent me)
                    {
                    }

                    @Override
                    public void mouseExited(MouseEvent me)
                    {
                    }
                });
                //buttonMaze[r][c].addActionListener(action);

                buttonMaze[r][c].setSize(DEFAULT_SIZE, DEFAULT_SIZE);
                switch (maze.getMaze()[r][c])
                {
                    case 0:
                        buttonMaze[r][c].setValue("0");
                        break;
                    case 1:
                        buttonMaze[r][c].setValue("1");
                        break;
                    case 2:
                        buttonMaze[r][c].setValue("2");
                        break;
                    case 3:
                        buttonMaze[r][c].setValue("3");
                        break;
                    case 4:
                        buttonMaze[r][c].setValue("4");
                        break;
                    case 5:
                        buttonMaze[r][c].setValue("5");
                        break;
                    case 6:
                        buttonMaze[r][c].setValue("6");
                        break;
                    case 7:
                        buttonMaze[r][c].setValue("7");
                        break;
                    case 8:
                        buttonMaze[r][c].setValue("8");
                        break;
                    case 9:
                        buttonMaze[r][c].setValue("9");
                        break;
                }
                buttonMaze[r][c].setVisible(true);

                posX = (posX + DEFAULT_SPACE) % (maze.getColumns() * DEFAULT_SPACE);
                buttonMaze[r][c].setLocation(posX, posY);
                jPanel1.add(buttonMaze[r][c]);
            }

        }
        this.pack();
        this.setSize(maze.getColumns() * DEFAULT_SPACE + 15, maze.getRows() * DEFAULT_SPACE + 90);
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jPanel2 = new javax.swing.JPanel();
        jButton4 = new javax.swing.JButton();
        jCheckBox1 = new javax.swing.JCheckBox();
        jButton1 = new javax.swing.JButton();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        jMenuItem1 = new javax.swing.JMenuItem();
        jMenuItem3 = new javax.swing.JMenuItem();
        jMenuItem4 = new javax.swing.JMenuItem();
        jMenuItem2 = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setResizable(false);

        jPanel1.setName("");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 0, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 471, Short.MAX_VALUE)
        );

        jButton4.setText("AutoSolve");
        jButton4.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton4ActionPerformed(evt);
            }
        });

        jCheckBox1.setSelected(true);
        jCheckBox1.setText("Show Log");
        jCheckBox1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBox1ActionPerformed(evt);
            }
        });

        jButton1.setText("Cheat");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jButton4)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jCheckBox1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jButton1)
                .addContainerGap(295, Short.MAX_VALUE))
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(jButton4)
                .addComponent(jCheckBox1)
                .addComponent(jButton1))
        );

        jMenu1.setText("File");

        jMenuItem1.setText("New Game");
        jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem1ActionPerformed(evt);
            }
        });
        jMenuItem1.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                jMenuItem1KeyPressed(evt);
            }
            public void keyReleased(java.awt.event.KeyEvent evt) {
                jMenuItem1KeyReleased(evt);
            }
        });
        jMenu1.add(jMenuItem1);

        jMenuItem3.setText("Configure");
        jMenuItem3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem3ActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem3);

        jMenuItem4.setText("N/U Tree");
        jMenuItem4.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem4ActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem4);

        jMenuItem2.setText("Exit");
        jMenuItem2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem2ActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem2);

        jMenuBar1.add(jMenu1);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jMenuItem1ActionPerformed
    {//GEN-HEADEREND:event_jMenuItem1ActionPerformed
        newGame();
    }//GEN-LAST:event_jMenuItem1ActionPerformed

    private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem2ActionPerformed
        System.exit(0);
    }//GEN-LAST:event_jMenuItem2ActionPerformed

    private void jMenuItem1KeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jMenuItem1KeyPressed
        // TODO add your handling code here:
    }//GEN-LAST:event_jMenuItem1KeyPressed

    private void jMenuItem1KeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jMenuItem1KeyReleased
    }//GEN-LAST:event_jMenuItem1KeyReleased

    private void jMenuItem3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem3ActionPerformed
        Config conf = new Config(this);
        conf.setVisible(true);
    }//GEN-LAST:event_jMenuItem3ActionPerformed

    private void jButton4ActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jButton4ActionPerformed
    {//GEN-HEADEREND:event_jButton4ActionPerformed
        // TODO add your handling code here:
        autoSolve();
    }//GEN-LAST:event_jButton4ActionPerformed

    private void jCheckBox1ActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jCheckBox1ActionPerformed
    {//GEN-HEADEREND:event_jCheckBox1ActionPerformed
        if (jCheckBox1.isSelected())
        {
            showLog = true;
        } else
        {
            showLog = false;
        }
    }//GEN-LAST:event_jCheckBox1ActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jButton1ActionPerformed
    {//GEN-HEADEREND:event_jButton1ActionPerformed
        cheat();
    }//GEN-LAST:event_jButton1ActionPerformed

    private void jMenuItem4ActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_jMenuItem4ActionPerformed
    {//GEN-HEADEREND:event_jMenuItem4ActionPerformed
        DrawTree dt = new DrawTree();
        dt.setLocation(this.getX() + this.getWidth() + 40, this.getY());
        dt.drawTree();
       // dt.setVisible(true);
    }//GEN-LAST:event_jMenuItem4ActionPerformed

    private void autoSolve()
    {
//        lastPosition = tree.addChild(lastPosition, "Begin Auto Solve");
        String logLine = "Begin Auto Solve";
        log.add(logLine);
        if (countRevealed == 0)
        {
            randomClick();
        }
        while (((countRevealed <= (maze.getTotalToBeReaveled()))
                && !endOfGame()))
        {

            while (remainsAreFree())
            {
                remainsAreFree();
            }

            while (remainsAreBomb())
            {
                remainsAreBomb();
            }

            if (!remainsAreBomb() && !remainsAreFree())
            {
                randomClick();
            }
        }

        //endOfGame();
    }

    private void randomClick()
    {
        int xx, yy;
        int rows = maze.getRows();
        int columns = maze.getColumns();
        xx = (int) (Math.random() * columns);
        yy = (int) (Math.random() * rows);
        while (!(actualState[yy][xx] == null) && !buttonMaze[yy][xx].isFlagged())
        {
            xx = (int) (Math.random() * columns);
            yy = (int) (Math.random() * rows);
        }
        buttonMaze[yy][xx].setSelected(true);
        if (buttonMaze[yy][xx].getValue().equals("9"))
        {
            bombClick = true;
        }
        //     lastPosition = tree.addChild(lastPosition, "Random Click At X-Y " + xx + "-" + yy);
        String logLine = "Random Click At (X,Y) (" + xx + "," + yy + ")";
        log.add(logLine);
    }
    
    /**
     * @return the rPressed
     */
    public int getrPressed()
    {
        return yPressed;
    }

    /**
     * @param rPressed the rPressed to set
     */
    public void setrPressed(int rPressed)
    {
        this.yPressed = rPressed;
    }

    /**
     * @return the cPressed
     */
    public int getcPressed()
    {
        return xPressed;
    }

    /**
     * @param cPressed the cPressed to set
     */
    public void setcPressed(int cPressed)
    {
        this.xPressed = cPressed;
    }

    private boolean checkNeighborhood(int x, int y)
    {
        // Color color = Color.ORANGE;
        boolean found = false;

        if (x + 1 < maze.getColumns()
                && !buttonMaze[y][x + 1].isSelected()
                && !buttonMaze[y][x + 1].isFlagged()
                && maze.getMaze()[y][x + 1] == 0)
        {
            //System.out.println(x + " - " + y);
            buttonMaze[y][x + 1].setSelected(true);
            // buttonMaze[y][x + 1].setBackground(color);
            checkNeighborhood(x + 1, y);
            found = true;
        }
        if (x - 1 >= 0
                && !buttonMaze[y][x - 1].isSelected()
                && !buttonMaze[y][x - 1].isFlagged()
                && maze.getMaze()[y][x - 1] == 0)
        {
            // System.out.println(x + " - " + y);
            buttonMaze[y][x - 1].setSelected(true);
            checkNeighborhood(x - 1, y);
            found = true;
        }

        if (y + 1 < maze.getRows()
                && !buttonMaze[y + 1][x].isSelected()
                && !buttonMaze[y + 1][x].isFlagged()
                && maze.getMaze()[y + 1][x] == 0)
        {
            buttonMaze[y + 1][x].setSelected(true);
            // buttonMaze[y + 1][x].setBackground(color);
            checkNeighborhood(x, y + 1);
            found = true;
        }
        if (y - 1 >= 0
                && !buttonMaze[y - 1][x].isSelected()
                && !buttonMaze[y - 1][x].isFlagged()
                && maze.getMaze()[y - 1][x] == 0)
        {
            buttonMaze[y - 1][x].setSelected(true);
            // buttonMaze[y - 1][x].setBackground(color);
            checkNeighborhood(x, y - 1);
            found = true;
        }
        if (y - 1 >= 0 && x - 1 >= 0
                && !buttonMaze[y - 1][x - 1].isSelected()
                && !buttonMaze[y - 1][x - 1].isFlagged()
                && maze.getMaze()[y - 1][x - 1] == 0)
        {
            buttonMaze[y - 1][x - 1].setSelected(true);
            // buttonMaze[y - 1][x - 1].setBackground(color);
            checkNeighborhood(x - 1, y - 1);
            found = true;
        }
        if (y - 1 >= 0
                && x + 1 < maze.getColumns()
                && !buttonMaze[y - 1][x + 1].isSelected()
                && !buttonMaze[y - 1][x + 1].isFlagged()
                && maze.getMaze()[y - 1][x + 1] == 0)
        {
            buttonMaze[y - 1][x + 1].setSelected(true);
            // buttonMaze[y - 1][x + 1].setBackground(color);
            checkNeighborhood(x + 1, y - 1);
            found = true;
        }
        if (y + 1 < maze.getRows()
                && x - 1 >= 0
                && !buttonMaze[y + 1][x - 1].isSelected()
                && !buttonMaze[y + 1][x - 1].isFlagged()
                && maze.getMaze()[y + 1][x - 1] == 0)
        {
            buttonMaze[y + 1][x - 1].setSelected(true);
            //buttonMaze[y + 1][x - 1].setBackground(color);
            checkNeighborhood(x - 1, y + 1);
            found = true;
        }
        if (y + 1 < maze.getRows()
                && x + 1 < maze.getColumns()
                && !buttonMaze[y + 1][x + 1].isSelected()
                && !buttonMaze[y + 1][x + 1].isFlagged()
                && maze.getMaze()[y + 1][x + 1] == 0)
        {
            buttonMaze[y + 1][x + 1].setSelected(true);
            //buttonMaze[y + 1][x + 1].setBackground(color);
            checkNeighborhood(x + 1, y + 1);
            found = true;
        }
        return found;
    }

    private void checkZero()
    {
        checkNeighborhood(xPressed, yPressed);
        log.add("Revealing Zeroes At X-Y " + xPressed + "-" + yPressed);
    }

    public void checkClick()
    {
        if (maze.getMaze()[yPressed][xPressed] == 9)
        {
            revealBombs();
            bombClick=true;

        } else if (maze.getMaze()[yPressed][xPressed] == 0)
        {
            checkZero();
        }

        endOfGame();

    }

    public boolean endOfGame()
    {
        boolean again;
        if (this.countRevealed == maze.getTotalToBeReaveled() && !bombClick)
        {
            again = confirmar(this, "Start Again?", "End Of Game");
            if (again)
            {
                newGame();
            } else if (showLog)
            {
                lr.setLocation(this.getX() + this.getWidth() + 40, this.getY());
                lr.setLog(log);
                lr.setSize(lr.getWidth(), Toolkit.getDefaultToolkit().getScreenSize().height - 60);
                lr.setVisible(true);
                //        DrawTree dt = new DrawTree();
                //       dt.setLocation(this.getX() + this.getWidth() + 40, this.getY());
//        dt.setTree(tree);
            }

            return true;

        } else if (bombClick)
        {
            revealBombs();
            again = confirmar(this, "Start Again?", "End Of Game");
            if (again)
            {
                newGame();
            } else if (showLog)
            {
                lr.setLocation(this.getX() + this.getWidth() + 40, this.getY());
                lr.setLog(log);
                lr.setSize(lr.getWidth(), Toolkit.getDefaultToolkit().getScreenSize().height - 60);
                lr.setVisible(true);
                //      DrawTree dt = new DrawTree();
                //      dt.setLocation(this.getX() + this.getWidth() + 40, this.getY());
                //      dt.setTree(tree);
            }
            return true;
        } else
        {
            // System.out.println("FALSE");
            return false;
        }
    }

    public void revealBombs()
    {
        String logLine = "REVEALING BOMBS - END OF GAME";
        log.add(logLine);
        buttonMaze[xPressed][yPressed].setSelected(true);

        int[][] mazeint = this.maze.getMaze();

        for (int x = 0; x < this.maze.getRows(); x++)
        {
            for (int y = 0; y < this.maze.getColumns(); y++)
            {
                    buttonMaze[x][y].setSelected(true);
                
            }
        }
    }

    public void cheat()
    {
        int[][] mazeint = this.maze.getMaze();

        for (int x = 0; x < this.maze.getRows(); x++)
        {
            for (int y = 0; y < this.maze.getColumns(); y++)
            {
                if (mazeint[x][y] < 9 && !buttonMaze[x][y].isSelected())
                {
                    log.add("CheatClick X-Y " + x + "-" + y + " Value = " + mazeint[x][y]);
                    buttonMaze[x][y].setSelected(true);
                }
            }
        }
        endOfGame();
    }

    public static boolean confirmar(Component comp, String aviso, String titulo)
    {
        Object[] options =
        {
            "Yes", "No - Show Log"
        };
        int i = JOptionPane.showOptionDialog(comp,
                aviso, titulo,
                JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null,
                options, options[1]);

        if (i == JOptionPane.YES_OPTION)
        {
            return true;
        }
        return false;
    }
    /**
     * @param args the command line arguments
     */
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton4;
    private javax.swing.JCheckBox jCheckBox1;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JMenuItem jMenuItem2;
    private javax.swing.JMenuItem jMenuItem3;
    private javax.swing.JMenuItem jMenuItem4;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    // End of variables declaration//GEN-END:variables

    private void newGame()
    {
        this.maze.generate();
        createMaze();
        this.countRevealed = 0;
        this.bombClick = false;
        this.actualState = new String[maze.getColumns()][maze.getRows()];
        this.countPFlagged = 0;
//        this.tree = new Tree("BEGIN");
//        this.lastPosition=tree.root();
    }

    public void setBombClick(boolean bombClick)
    {
        this.bombClick = bombClick;
    }

    public mazeButton[][] getButtonMaze()
    {
        return buttonMaze;
    }

    public int getCountRevealed()
    {
        return countRevealed;
    }

    public void setCountRevealed(int countRevealed)
    {
        this.countRevealed = countRevealed;
    }

    public String[][] getActualState()
    {
        return actualState;
    }

    public void setMaze(Maze maze)
    {
        this.maze = maze;
        createMaze();
        this.countRevealed = 0;
        bombClick = false;
    }

    //MARK AROUND MAX FREE TILES DISCOVERED
    private boolean remainsAreBomb()
    {
        boolean changed = false;
        for (int x = 0; x < maze.getColumns(); x++)
        {
            for (int y = 0; y < maze.getRows(); y++)
            {
                int value = Integer.parseInt(buttonMaze[y][x].getValue());
                int countBomb = 0;
                int countDiscovered = 0;
                int totalTiles = 8;

                if (buttonMaze[y][x].isSelected() && !buttonMaze[y][x].isFlagged() && value >= 1) //THEN CHECK NEIGHBOORS TO SE IF ALL THE BOMBS HAVE BEEN FOUNDED OR MARK WITH ASK THE BLANK ONES
                {
                    if (x + 1 < maze.getColumns())
                    {
                        if (buttonMaze[y][x + 1].isFlagged() && buttonMaze[y][x + 1].getFlag().toLowerCase().equals("pflag"))
                        {
                            countBomb++;
                        } else if (buttonMaze[y][x + 1].isSelected())
                        {
                            countDiscovered++;
                        }
                    } else
                    {
                        totalTiles--;
                    }
                    if (x - 1 >= 0)
                    {
                        if (buttonMaze[y][x - 1].isFlagged() && buttonMaze[y][x - 1].getFlag().toLowerCase().equals("pflag"))
                        {
                            countBomb++;
                        } else if (buttonMaze[y][x - 1].isSelected())
                        {
                            countDiscovered++;
                        }
                    } else
                    {
                        totalTiles--;
                    }

                    if (y + 1 < maze.getRows())
                    {
                        if (buttonMaze[y + 1][x].isFlagged() && buttonMaze[y + 1][x].getFlag().toLowerCase().equals("pflag"))
                        {
                            countBomb++;
                        } else if (buttonMaze[y + 1][x].isSelected())
                        {
                            countDiscovered++;
                        }
                    } else
                    {
                        totalTiles--;
                    }
                    if (y - 1 >= 0)
                    {
                        if ((buttonMaze[y - 1][x].isFlagged() && buttonMaze[y - 1][x].getFlag().toLowerCase().equals("pflag")))
                        {
                            countBomb++;
                        } else if (buttonMaze[y - 1][x].isSelected())
                        {
                            countDiscovered++;
                        }
                    } else
                    {
                        totalTiles--;
                    }
                    if (y - 1 >= 0 && x - 1 >= 0)
                    {
                        if (buttonMaze[y - 1][x - 1].isFlagged() && buttonMaze[y - 1][x - 1].getFlag().toLowerCase().equals("pflag"))
                        {
                            countBomb++;
                        } else if (buttonMaze[y - 1][x - 1].isSelected())
                        {
                            countDiscovered++;
                        }
                    } else
                    {
                        totalTiles--;
                    }
                    if (y - 1 >= 0
                            && x + 1 < maze.getColumns())
                    {
                        if (buttonMaze[y - 1][x + 1].isFlagged() && buttonMaze[y - 1][x + 1].getFlag().toLowerCase().equals("pflag"))
                        {
                            countBomb++;
                        } else if (buttonMaze[y - 1][x + 1].isSelected())
                        {
                            countDiscovered++;
                        }
                    } else
                    {
                        totalTiles--;
                    }
                    if (y + 1 < maze.getRows()
                            && x - 1 >= 0)
                    {
                        if (buttonMaze[y + 1][x - 1].isFlagged() && buttonMaze[y + 1][x - 1].getFlag().toLowerCase().equals("pflag"))
                        {
                            countBomb++;
                        } else if (buttonMaze[y + 1][x - 1].isSelected())
                        {
                            countDiscovered++;
                        }
                    } else
                    {
                        totalTiles--;
                    }
                    if (y + 1 < maze.getRows()
                            && x + 1 < maze.getColumns())
                    {
                        if (buttonMaze[y + 1][x + 1].isFlagged() && buttonMaze[y + 1][x + 1].getFlag().toLowerCase().equals("pflag"))
                        {
                            countBomb++;
                        } else if (buttonMaze[y + 1][x + 1].isSelected())
                        {
                            countDiscovered++;
                        }
                    } else
                    {
                        totalTiles--;
                    }

                    if ((value - countBomb) > 0)
                    {
                        if (((totalTiles - (countDiscovered + countBomb)) == (value - countBomb))) //THEN ALL REMAINS ARE BOMBS
                        {
                            String posSelected = "";
                            //lastPosition = tree.addChild(lastPosition, "Remains are Bomb At X-Y" + x + "-" + y);
                            changed = true;
                            if (x + 1 < maze.getColumns()
                                    && !buttonMaze[y][x + 1].isSelected()
                                    && !buttonMaze[y][x + 1].isFlagged())
                            {
                                // System.out.println("x+1");
                                buttonMaze[y][x + 1].setFlag("pflag");
                                //  tree.addChild(lastPosition, "Set Flag At X-Y" + (x + 1) + "-" + (y));
                                posSelected += "\t" + (x + 1) + "-" + (y) + "\n";
                            }
                            if (x - 1 >= 0
                                    && !buttonMaze[y][x - 1].isSelected()
                                    && !buttonMaze[y][x - 1].isFlagged())
                            {
                                //   System.out.println("x-1");
                                buttonMaze[y][x - 1].setFlag("pflag");
                                //  tree.addChild(lastPosition, "Set Flag At X-Y" + (x - 1) + "-" + (y));
                                posSelected += "\t" + (x - 1) + "-" + (y) + "\n";
                            }

                            if (y + 1 < maze.getRows()
                                    && !buttonMaze[y + 1][x].isSelected()
                                    && !buttonMaze[y + 1][x].isFlagged())
                            {
                                //   System.out.println("Y+1");
                                buttonMaze[y + 1][x].setFlag("pflag");
                                // tree.addChild(lastPosition, "Set Flag At X-Y" + (x) + "-" + (y + 1));
                                posSelected += "\t" + (x) + "-" + (y + 1) + "\n";
                            }
                            if (y - 1 >= 0
                                    && !buttonMaze[y - 1][x].isSelected()
                                    && !buttonMaze[y - 1][x].isFlagged())
                            {
                                //   System.out.println("y-1");
                                buttonMaze[y - 1][x].setFlag("pflag");
                                // tree.addChild(lastPosition, "Set Flag At X-Y" + (x) + "-" + (y - 1));
                                posSelected += "\t" + (x) + "-" + (y - 1) + "\n";
                            }
                            if (y - 1 >= 0 && x - 1 >= 0
                                    && !buttonMaze[y - 1][x - 1].isSelected()
                                    && !buttonMaze[y - 1][x - 1].isFlagged())
                            {
                                //   System.out.println("y-1 x-1");
                                buttonMaze[y - 1][x - 1].setFlag("pflag");
                                // tree.addChild(lastPosition, "Set Flag At X-Y" + (x - 1) + "-" + (y - 1));
                                posSelected += "\t" + (x - 1) + "-" + (y - 1) + "\n";
                            }
                            if (y - 1 >= 0
                                    && x + 1 < maze.getColumns()
                                    && !buttonMaze[y - 1][x + 1].isSelected()
                                    && !buttonMaze[y - 1][x + 1].isFlagged())
                            {
                                //   System.out.println("y-1 x+1");
                                buttonMaze[y - 1][x + 1].setFlag("pflag");
                                // tree.addChild(lastPosition, "Set Flag At X-Y" + (x + 1) + "-" + (y - 1));
                                posSelected += "\t" + (x + 1) + "-" + (y - 1) + "\n";
                            }
                            if (y + 1 < maze.getRows()
                                    && x - 1 >= 0
                                    && !buttonMaze[y + 1][x - 1].isSelected()
                                    && !buttonMaze[y + 1][x - 1].isFlagged())
                            {
                                //   System.out.println("y+1 x-1");
                                buttonMaze[y + 1][x - 1].setFlag("pflag");
                                // tree.addChild(lastPosition, "Set Flag At X-Y" + (x + 1) + "-" + (y - 1));
                                posSelected += "\t" + (x - 1) + "-" + (y + 1) + "\n";
                            }
                            if (y + 1 < maze.getRows()
                                    && x + 1 < maze.getColumns()
                                    && !buttonMaze[y + 1][x + 1].isSelected()
                                    && !buttonMaze[y + 1][x + 1].isFlagged())
                            {
                                //    System.out.println("y+1 x+1");
                                buttonMaze[y + 1][x + 1].setFlag("pflag");
                                // tree.addChild(lastPosition, "Set Flag At X-Y" + (x + 1) + "-" + (y + 1));
                                posSelected += "\t" + (x + 1) + "-" + (y + 1) + "\n";
                            }
//                            lastPosition = tree.addChild(lastPosition, posSelected);
                            if (posSelected.length() > 1)
                            {
                                String logLine = "Remains are Bomb At (X,Y)" + "(" + x + "," + y + ")";
                                log.add(logLine);
                                String titlePosSelected = "Flags Set at X-Y";
                                log.add(titlePosSelected);
                                log.add(posSelected);
                            }
                        }
                    }
                }

            }
        }
        return changed;

    }
    //Mark Aroud Max Bombs Found

    private boolean remainsAreFree()
    {
        boolean changed = false;

        for (int x = 0; x < maze.getColumns(); x++)
        {
            for (int y = 0; y < maze.getRows(); y++)
            {
                int value = Integer.parseInt(buttonMaze[y][x].getValue());
                int countBomb = 0;
                int totalTiles = 8;
                /*
                 * IS BOMB IF (buttonMaze[y][x].isSelected()||
                 * (buttonMaze[y][x].isFlagged()&&
                 * buttonMaze[y][x].getFlag().toLowerCase().equals("pflag"))
                 */
                if (buttonMaze[y][x].isSelected() && !buttonMaze[y][x].isFlagged()) //THEN CHECK NEIGHBOORS TO SE IF ALL THE BOMBS HAVE BEEN FOUNDED OR MARK WITH ASK THE BLANK ONES
                {
                    if (x + 1 < maze.getColumns())
                    {
                        if (buttonMaze[y][x + 1].isFlagged() && buttonMaze[y][x + 1].getFlag().toLowerCase().equals("pflag"))
                        {
                            countBomb++;
                        }
                    } else
                    {
                        totalTiles--;
                    }
                    if (x - 1 >= 0)
                    {
                        if (buttonMaze[y][x - 1].isFlagged() && buttonMaze[y][x - 1].getFlag().toLowerCase().equals("pflag"))
                        {
                            countBomb++;
                        }
                    } else
                    {
                        totalTiles--;
                    }

                    if (y + 1 < maze.getRows())
                    {
                        if (buttonMaze[y + 1][x].isFlagged() && buttonMaze[y + 1][x].getFlag().toLowerCase().equals("pflag"))
                        {
                            countBomb++;
                        }
                    } else
                    {
                        totalTiles--;
                    }
                    if (y - 1 >= 0)
                    {
                        if ((buttonMaze[y - 1][x].isFlagged() && buttonMaze[y - 1][x].getFlag().toLowerCase().equals("pflag")))
                        {
                            countBomb++;
                        }
                    } else
                    {
                        totalTiles--;
                    }
                    if (y - 1 >= 0 && x - 1 >= 0)
                    {
                        if (buttonMaze[y - 1][x - 1].isFlagged() && buttonMaze[y - 1][x - 1].getFlag().toLowerCase().equals("pflag"))
                        {
                            countBomb++;
                        }
                    } else
                    {
                        totalTiles--;
                    }
                    if (y - 1 >= 0
                            && x + 1 < maze.getColumns())
                    {
                        if (buttonMaze[y - 1][x + 1].isFlagged() && buttonMaze[y - 1][x + 1].getFlag().toLowerCase().equals("pflag"))
                        {
                            countBomb++;
                        }
                    } else
                    {
                        totalTiles--;
                    }
                    if (y + 1 < maze.getRows()
                            && x - 1 >= 0)
                    {
                        if (buttonMaze[y + 1][x - 1].isFlagged() && buttonMaze[y + 1][x - 1].getFlag().toLowerCase().equals("pflag"))
                        {
                            countBomb++;
                        }
                    } else
                    {
                        totalTiles--;
                    }
                    if (y + 1 < maze.getRows()
                            && x + 1 < maze.getColumns())
                    {
                        if (buttonMaze[y + 1][x + 1].isFlagged() && buttonMaze[y + 1][x + 1].getFlag().toLowerCase().equals("pflag"))
                        {
                            countBomb++;
                        }
                    } else
                    {
                        totalTiles--;
                    }

                    if (countBomb == value) //ALL BOMBS HAS BEEN DISCOVERED THEN SELECT REMAINS
                    {
                        String posSelected = "";
//                            lastPosition = tree.addChild(lastPosition, "Remains are Free At X-Y" + x + "-" + y);

                        if (x + 1 < maze.getColumns()
                                && !buttonMaze[y][x + 1].isSelected()
                                && !buttonMaze[y][x + 1].isFlagged())
                        {
                            buttonMaze[y][x + 1].setSelected(true);
                            changed = true;
                            //          tree.addChild(lastPosition, "Select X-Y" + (x + 1) + "-" + (y));
                            posSelected += "\t" + (x + 1) + "-" + (y) + "\n";
                        }
                        if (x - 1 >= 0
                                && !buttonMaze[y][x - 1].isSelected()
                                && !buttonMaze[y][x - 1].isFlagged())
                        {
                            buttonMaze[y][x - 1].setSelected(true);
                            changed = true;
                            //       tree.addChild(lastPosition, "Select X-Y" + (x - 1) + "-" + (y));
                            posSelected += "\t" + (x - 1) + "-" + (y) + "\n";
                        }

                        if (y + 1 < maze.getRows()
                                && !buttonMaze[y + 1][x].isSelected()
                                && !buttonMaze[y + 1][x].isFlagged())
                        {
                            buttonMaze[y + 1][x].setSelected(true);
                            changed = true;
                            //     tree.addChild(lastPosition, "Select X-Y" + (x) + "-" + (y + 1));
                            posSelected += "\t" + (x) + "-" + (y + 1) + "\n";
                        }
                        if (y - 1 >= 0
                                && !buttonMaze[y - 1][x].isSelected()
                                && !buttonMaze[y - 1][x].isFlagged())
                        {
                            buttonMaze[y - 1][x].setSelected(true);
                            changed = true;
                            //   tree.addChild(lastPosition, "Select X-Y" + (x) + "-" + (y - 1));
                            posSelected += "\t" + (x) + "-" + (y - 1) + "\n";
                        }
                        if (y - 1 >= 0 && x - 1 >= 0
                                && !buttonMaze[y - 1][x - 1].isSelected()
                                && !buttonMaze[y - 1][x - 1].isFlagged())
                        {
                            buttonMaze[y - 1][x - 1].setSelected(true);
                            changed = true;
                            //    tree.addChild(lastPosition, "Select X-Y" + (x - 1) + "-" + (y - 1));
                            posSelected += "\t" + (x - 1) + "-" + (y - 1) + "\n";
                        }
                        if (y - 1 >= 0
                                && x + 1 < maze.getColumns()
                                && !buttonMaze[y - 1][x + 1].isSelected()
                                && !buttonMaze[y - 1][x + 1].isFlagged())
                        {
                            buttonMaze[y - 1][x + 1].setSelected(true);
                            changed = true;
                            //    tree.addChild(lastPosition, "Select X-Y" + (x + 1) + "-" + (y - 1));
                            posSelected += "\t" + (x + 1) + "-" + (y - 1) + "\n";
                        }
                        if (y + 1 < maze.getRows()
                                && x - 1 >= 0
                                && !buttonMaze[y + 1][x - 1].isSelected()
                                && !buttonMaze[y + 1][x - 1].isFlagged())
                        {
                            buttonMaze[y + 1][x - 1].setSelected(true);
                            changed = true;
                            //   tree.addChild(lastPosition, "Select X-Y" + (x - 1) + "-" + (y + 1));
                            posSelected += "\t" + (x - 1) + "-" + (y + 1) + "\n";
                        }
                        if (y + 1 < maze.getRows()
                                && x + 1 < maze.getColumns()
                                && !buttonMaze[y + 1][x + 1].isSelected()
                                && !buttonMaze[y + 1][x + 1].isFlagged())
                        {
                            buttonMaze[y + 1][x + 1].setSelected(true);
                            changed = true;
                            //    tree.addChild(lastPosition, "Select X-Y" + (x + 1) + "-" + (y + 1));
                            posSelected += "\t" + (x + 1) + "-" + (y + 1) + "\n";
                        }

//                            lastPosition = tree.addChild(lastPosition, posSelected);
                        if (posSelected.length() > 1)
                        {
                            String logLine = "Remains are Free At (X,Y)" + "(" + x + "," + y + ")";
                            log.add(logLine);
                            String titlePosSelected = "Squares Selected at X-Y";
                            log.add(titlePosSelected);
                            log.add(posSelected);
                        }
                    }

                }
            }
        }
        return changed;
    }

    public int getCountPFlagged()
    {
        return countPFlagged;
    }

    public void setCountPFlagged(int countPFlagged)
    {
        this.countPFlagged = countPFlagged;
    }
}
